/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/02/18
* File: plane.h
**/

#pragma once

#include "vector3.h"

namespace HY
{
/// Surface in three-dimensional space.
class Plane
{
public:
	/// Construct undefined.
	Plane()
	{
	}

	/// Copy-construct from another plane.
	Plane(const Plane& plane) :
	normal_(plane.normal_),
		intercept_(plane.intercept_)
	{
	}

	/// Construct from 3 vertices.
	Plane(const Vector3& v0, const Vector3& v1, const Vector3& v2)
	{
		Define(v0, v1, v2);
	}

	/// Construct from a normal vector and a point on the plane.
	Plane(const Vector3& normal, const Vector3& point)
	{
		Define(normal, point);
	}

	/// Define from 3 vertices.
	void Define(const Vector3& v0, const Vector3& v1, const Vector3& v2)
	{
		Vector3 dist1 = v1 - v0;
		Vector3 dist2 = v2 - v0;

		normal_ = (dist1.CrossProduct(dist2)).Normalized();
		absNormal_ = Vector3(Abs(normal_.x_), Abs(normal_.y_), Abs(normal_.z_));
		intercept_ = normal_.DotProduct(v0);
	}

	/// Define from a normal and a point.
	void Define(const Vector3& normal, const Vector3& point)
	{
		normal_ = normal;
		absNormal_ = Vector3(Abs(normal_.x_), Abs(normal_.y_), Abs(normal_.z_));
		intercept_ = normal_.DotProduct(point);
	}

	/// Return signed distance to a point.
	float Distance(const Vector3& point) const { return normal_.DotProduct(point) - intercept_; }

	/// Plane normal.
	Vector3 normal_;
	/// Plane absolute normal.
	Vector3 absNormal_;
	/// Plane intercept parameter.
	float intercept_;
};

}